%store -r ecoregions_gdf occurrence_dfSTEP 5: Plot the Veery observations by month
First thing first – let’s load your stored variables and import libraries.
Try It: Import packages
In the imports cell, we’ve included some packages that you will need. Add imports for packages that will help you:
- Make interactive maps with vector data
# Get month names
import calendar
# Libraries for Dynamic mapping
import cartopy.crs as ccrs
import panel as pnSee our solution!
# Get month names
import calendar
# Libraries for Dynamic mapping
import cartopy.crs as ccrs
import hvplot.pandas
import panel as pnCreate a simplified GeoDataFrame for plotting
Plotting larger files can be time consuming. The code below will streamline plotting with hvplot by simplifying the geometry, projecting it to a Mercator projection that is compatible with geoviews, and cropping off areas in the Arctic.
Try It: Simplify ecoregion data
Download and save ecoregion boundaries from the EPA:
- Simplify the ecoregions with
.simplify(.05), and save it back to thegeometrycolumn. - Change the Coordinate Reference System (CRS) to Mercator with
.to_crs(ccrs.Mercator()) - Use the plotting code that is already in the cell to check that the plotting runs quickly (less than a minute) and looks the way you want, making sure to change
gdfto YOURGeoDataFramename.
# Simplify the geometry to speed up processing
# Change the CRS to Mercator for mapping
# Check that the plot runs in a reasonable amount of time
gdf.hvplot(geo=True, crs=ccrs.Mercator())See our solution!
# Simplify the geometry to speed up processing
ecoregions_gdf.geometry = ecoregions_gdf.simplify(
.05, preserve_topology=False)
# Change the CRS to Mercator for mapping
ecoregions_gdf = ecoregions_gdf.to_crs(ccrs.Mercator())
# Check that the plot runs
ecoregions_gdf.hvplot(geo=True, crs=ccrs.Mercator())
Try It: Map migration over time
- If applicable, replace any variable names with the names you defined previously.
- Replace
column_name_used_for_ecoregion_colorandcolumn_name_used_for_sliderwith the column names you wish to use. - Customize your plot with your choice of title, tile source, color map, and size.
Note
Your plot will probably still change months very slowly in your Jupyter notebook, because it calculates each month’s plot as needed. Open up the saved HTML file to see faster performance!
# Join the occurrences with the plotting GeoDataFrame
occurrence_gdf = ecoregions_gdf.join(occurrence_df)
# Get the plot bounds so they don't change with the slider
xmin, ymin, xmax, ymax = occurrence_gdf.total_bounds
# Plot occurrence by ecoregion and month
migration_plot = (
occurrence_gdf
.hvplot(
c=column_name_used_for_shape_color,
groupby=column_name_used_for_slider,
# Use background tiles
geo=True, crs=ccrs.Mercator(), tiles='CartoLight',
title="Your Title Here",
xlim=(xmin, xmax), ylim=(ymin, ymax),
frame_height=600,
widget_location='bottom'
)
)
# Save the plot
migration_plot.save('migration.html', embed=True)
# Show the plot
migration_plotSee our solution!
# Join the occurrences with the plotting GeoDataFrame
occurrence_gdf = ecoregions_gdf.join(occurrence_df)
# Get the plot bounds so they don't change with the slider
xmin, ymin, xmax, ymax = occurrence_gdf.total_bounds
# Define the slider widget
slider = pn.widgets.DiscreteSlider(
name='month',
options={calendar.month_name[i]: i for i in range(1, 13)}
)
# Plot occurrence by ecoregion and month
migration_plot = (
occurrence_gdf
.hvplot(
c='norm_occurrences',
groupby='month',
# Use background tiles
geo=True, crs=ccrs.Mercator(), tiles='CartoLight',
title="Veery migration",
xlim=(xmin, xmax), ylim=(ymin, ymax),
frame_height=600,
colorbar=False,
widgets={'month': slider},
widget_location='bottom'
)
)
# Save the plot (if possible)
try:
migration_plot.save('migration.html', embed=True)
except Exception as exc:
print('Could not save the migration plot due to the following error:')
print(exc)
# Show the plot
migration_plot 0%| | 0/12 [00:00<?, ?it/s] 8%|▊ | 1/12 [00:00<00:01, 6.82it/s] 17%|█▋ | 2/12 [00:00<00:01, 6.16it/s] 25%|██▌ | 3/12 [00:00<00:03, 2.62it/s] 33%|███▎ | 4/12 [00:01<00:03, 2.08it/s] 42%|████▏ | 5/12 [00:02<00:03, 2.04it/s] 50%|█████ | 6/12 [00:02<00:02, 2.05it/s] 58%|█████▊ | 7/12 [00:03<00:02, 1.95it/s] 67%|██████▋ | 8/12 [00:03<00:02, 1.70it/s] 75%|███████▌ | 9/12 [00:04<00:01, 1.79it/s] 83%|████████▎ | 10/12 [00:04<00:00, 2.29it/s] 92%|█████████▏| 11/12 [00:04<00:00, 2.74it/s]100%|██████████| 12/12 [00:04<00:00, 3.21it/s]
WARNING:bokeh.core.validation.check:W-1005 (FIXED_SIZING_MODE): 'fixed' sizing mode requires width and height to be set: figure(id='p19289', ...)